import { DIContainer } from '../../infrastructure/di';
import { IGameService, ServiceStatus, HealthCheckResult, ServiceEventType } from './IGameService';

/**
 * 服务注册信息
 */
interface ServiceRegistration {
    service: IGameService;
    config: ServiceRegistrationConfig;
    registeredAt: number;
}

/**
 * 服务注册配置
 */
interface ServiceRegistrationConfig {
    /** 是否单例 */
    singleton?: boolean;
    /** 生命周期管理 */
    lifecycle?: 'eager' | 'lazy';
    /** 启动优先级 */
    priority?: number;
    /** 是否启用健康检查 */
    enableHealthCheck?: boolean;
}

/**
 * 服务发现和管理接口
 */
export interface IServiceDiscovery {
    /** 获取服务 */
    getService<T extends IGameService>(serviceName: string): T;
    /** 检查服务是否存在 */
    hasService(serviceName: string): boolean;
    /** 获取所有服务状态 */
    getAllServiceStatus(): Map<string, ServiceStatus>;
    /** 获取健康的服务列表 */
    getHealthyServices(): string[];
    /** 获取不健康的服务列表 */
    getUnhealthyServices(): string[];
}

/**
 * 统一的服务注册管理器
 * 负责管理所有游戏服务的注册、发现、健康检查和生命周期
 */
export class UnifiedServiceRegistry implements IServiceDiscovery {
    private static instance: UnifiedServiceRegistry;
    private container: DIContainer;
    private services = new Map<string, ServiceRegistration>();
    private isInitialized = false;
    private healthCheckInterval?: NodeJS.Timeout;

    private constructor(container: DIContainer) {
        this.container = container;
    }

    /**
     * 获取单例实例
     */
    static getInstance(container?: DIContainer): UnifiedServiceRegistry {
        if (!this.instance) {
            if (!container) {
                throw new Error('Container is required for first initialization');
            }
            this.instance = new UnifiedServiceRegistry(container);
        }
        return this.instance;
    }

    /**
     * 注册服务
     */
    register<T extends IGameService>(
        serviceName: string, 
        serviceFactory: (container: DIContainer) => T,
        config: ServiceRegistrationConfig = {}
    ): void {
        if (this.services.has(serviceName)) {
            console.warn(`Service ${serviceName} is already registered, skipping...`);
            return;
        }

        const serviceConfig: ServiceRegistrationConfig = {
            singleton: true,
            lifecycle: 'lazy',
            priority: 0,
            enableHealthCheck: true,
            ...config
        };

        try {
            // 创建服务实例
            const service = serviceFactory(this.container);
            
            // 注册到DI容器
            this.container.register(serviceName, () => service, { 
                singleton: serviceConfig.singleton 
            });

            // 注册到服务注册表
            this.services.set(serviceName, {
                service,
                config: serviceConfig,
                registeredAt: Date.now()
            });

            console.log(`✅ Service registered: ${serviceName} (singleton: ${serviceConfig.singleton})`);

        } catch (error) {
            console.error(`❌ Failed to register service ${serviceName}:`, error);
            throw error;
        }
    }

    /**
     * 批量注册服务
     */
    registerBatch(registrations: Array<{
        name: string;
        factory: (container: DIContainer) => IGameService;
        config?: ServiceRegistrationConfig;
    }>): void {
        // 按优先级排序
        const sortedRegistrations = registrations.sort((a, b) => 
            (b.config?.priority || 0) - (a.config?.priority || 0)
        );

        for (const { name, factory, config } of sortedRegistrations) {
            this.register(name, factory, config);
        }
    }

    /**
     * 初始化所有服务
     */
    async initializeAll(): Promise<void> {
        if (this.isInitialized) {
            console.warn('Services already initialized');
            return;
        }

        console.log('🚀 Initializing all services...');

        // 获取所有需要eager初始化的服务，按优先级排序
        const eagerServices = Array.from(this.services.entries())
            .filter(([_, registration]) => registration.config.lifecycle === 'eager')
            .sort(([, a], [, b]) => (b.config.priority || 0) - (a.config.priority || 0));

        // 并行初始化eager服务
        const initPromises = eagerServices.map(async ([serviceName, registration]) => {
            try {
                console.log(`Initializing service: ${serviceName}`);
                await registration.service.init();
                console.log(`✅ Service initialized: ${serviceName}`);
            } catch (error) {
                console.error(`❌ Failed to initialize service ${serviceName}:`, error);
                throw new Error(`Service initialization failed: ${serviceName} - ${(error as Error).message}`);
            }
        });

        await Promise.all(initPromises);

        // 启动全局健康检查
        this.startGlobalHealthCheck();

        this.isInitialized = true;
        console.log('🎉 All services initialized successfully');
    }

    /**
     * 获取服务实例
     */
    getService<T extends IGameService>(serviceName: string): T {
        const registration = this.services.get(serviceName);
        if (!registration) {
            throw new Error(`Service not found: ${serviceName}`);
        }

        // 如果是lazy服务且未初始化，先初始化
        if (registration.config.lifecycle === 'lazy' && 
            registration.service.lifecycle === 'created') {
            registration.service.init().catch(error => {
                console.error(`Failed to lazy-initialize service ${serviceName}:`, error);
            });
        }

        return registration.service as T;
    }

    /**
     * 检查服务是否存在
     */
    hasService(serviceName: string): boolean {
        return this.services.has(serviceName);
    }

    /**
     * 获取所有服务状态
     */
    getAllServiceStatus(): Map<string, ServiceStatus> {
        const statusMap = new Map<string, ServiceStatus>();
        
        for (const [serviceName, registration] of this.services.entries()) {
            statusMap.set(serviceName, registration.service.getStatus());
        }
        
        return statusMap;
    }

    /**
     * 获取健康的服务列表
     */
    getHealthyServices(): string[] {
        const healthyServices: string[] = [];
        
        for (const [serviceName, registration] of this.services.entries()) {
            const status = registration.service.getStatus();
            if (status.isHealthy) {
                healthyServices.push(serviceName);
            }
        }
        
        return healthyServices;
    }

    /**
     * 获取不健康的服务列表
     */
    getUnhealthyServices(): string[] {
        const unhealthyServices: string[] = [];
        
        for (const [serviceName, registration] of this.services.entries()) {
            const status = registration.service.getStatus();
            if (!status.isHealthy) {
                unhealthyServices.push(serviceName);
            }
        }
        
        return unhealthyServices;
    }

    /**
     * 执行全局健康检查
     */
    async performGlobalHealthCheck(): Promise<Map<string, HealthCheckResult>> {
        const results = new Map<string, HealthCheckResult>();
        
        console.log('🔍 Performing global health check...');
        
        const checkPromises = Array.from(this.services.entries()).map(async ([serviceName, registration]) => {
            if (!registration.config.enableHealthCheck) {
                return;
            }
            
            try {
                const result = await registration.service.healthCheck();
                results.set(serviceName, result);
                
                if (!result.healthy) {
                    console.warn(`⚠️ Service unhealthy: ${serviceName} - ${result.message}`);
                }
            } catch (error) {
                const errorResult: HealthCheckResult = {
                    healthy: false,
                    message: `Health check error: ${(error as Error).message}`,
                    timestamp: Date.now()
                };
                results.set(serviceName, errorResult);
                console.error(`❌ Health check failed for ${serviceName}:`, error);
            }
        });

        await Promise.all(checkPromises);
        
        const healthyCount = Array.from(results.values()).filter(r => r.healthy).length;
        const totalCount = results.size;
        
        console.log(`🏥 Health check completed: ${healthyCount}/${totalCount} services healthy`);
        
        return results;
    }

    /**
     * 销毁所有服务
     */
    async destroyAll(): Promise<void> {
        console.log('🔄 Destroying all services...');

        // 停止健康检查
        if (this.healthCheckInterval) {
            clearInterval(this.healthCheckInterval);
            this.healthCheckInterval = undefined;
        }

        // 按相反优先级顺序销毁服务
        const servicesArray = Array.from(this.services.entries())
            .sort(([, a], [, b]) => (a.config.priority || 0) - (b.config.priority || 0));

        for (const [serviceName, registration] of servicesArray) {
            try {
                await registration.service.destroy();
                console.log(`✅ Service destroyed: ${serviceName}`);
            } catch (error) {
                console.error(`❌ Failed to destroy service ${serviceName}:`, error);
            }
        }

        this.services.clear();
        this.isInitialized = false;
        console.log('🎯 All services destroyed');
    }

    /**
     * 获取服务统计信息
     */
    getServiceStats(): {
        totalServices: number;
        healthyServices: number;
        unhealthyServices: number;
        initializationTime: number;
    } {
        const totalServices = this.services.size;
        const healthyServices = this.getHealthyServices().length;
        const unhealthyServices = this.getUnhealthyServices().length;
        
        // 计算最晚的服务注册时间作为初始化时间参考
        const latestRegistration = Math.max(...Array.from(this.services.values()).map(r => r.registeredAt));
        const initializationTime = latestRegistration > 0 ? Date.now() - latestRegistration : 0;

        return {
            totalServices,
            healthyServices,
            unhealthyServices,
            initializationTime
        };
    }

    /**
     * 启动全局健康检查定时器
     */
    private startGlobalHealthCheck(): void {
        // 每5分钟执行一次全局健康检查
        this.healthCheckInterval = setInterval(async () => {
            try {
                await this.performGlobalHealthCheck();
            } catch (error) {
                console.error('Global health check failed:', error);
            }
        }, 5 * 60 * 1000); // 5分钟

        console.log('🔍 Global health check started (every 5 minutes)');
    }

    /**
     * 获取服务依赖图
     */
    getDependencyGraph(): Map<string, string[]> {
        const dependencyGraph = new Map<string, string[]>();
        
        for (const [serviceName, registration] of this.services.entries()) {
            dependencyGraph.set(serviceName, registration.service.dependencies);
        }
        
        return dependencyGraph;
    }

    /**
     * 验证服务依赖图是否有循环依赖
     */
    validateDependencies(): { valid: boolean; circularDependencies?: string[] } {
        const dependencyGraph = this.getDependencyGraph();
        const visited = new Set<string>();
        const visiting = new Set<string>();
        
        const hasCycle = (serviceName: string): boolean => {
            if (visiting.has(serviceName)) {
                return true; // 找到循环依赖
            }
            if (visited.has(serviceName)) {
                return false; // 已经访问过，无循环
            }
            
            visiting.add(serviceName);
            
            const dependencies = dependencyGraph.get(serviceName) || [];
            for (const dependency of dependencies) {
                if (hasCycle(dependency)) {
                    return true;
                }
            }
            
            visiting.delete(serviceName);
            visited.add(serviceName);
            return false;
        };
        
        for (const serviceName of dependencyGraph.keys()) {
            if (hasCycle(serviceName)) {
                return { valid: false, circularDependencies: Array.from(visiting) };
            }
        }
        
        return { valid: true };
    }
}
